/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.common.base.util;

import com.je.common.auth.impl.PlatformOrganization;
import com.je.common.auth.impl.RealOrganization;
import com.je.common.auth.impl.RealOrganizationUser;
import com.je.common.auth.impl.account.Account;
import com.je.common.auth.impl.Department;
import com.je.common.auth.impl.DepartmentUser;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 获取当前线程用户工具类
 */
public class SecurityUserHolder {

    /**
     * 当前线程用户,在 SessionFilter 中添加。
     */
    private static final ThreadLocal<Account> threadLocal = new ThreadLocal<>();

    /**
     * 向 ThreadLocal 添加当前用户
     *
     * @param t 当前用户信息
     */
    public static void put(Account t) {
        threadLocal.set(t);
    }

    /**
     * 清空当前线程绑定的用户
     */
    public static void remove() {
        threadLocal.remove();
    }

    /**
     * 获取当前线程绑定的账号
     *
     * @return 当前用户
     */
    public static Account getCurrentAccount() {
        return threadLocal.get();
    }

    /**
     * 获取当前账户的机构
     * @return
     */
    public static PlatformOrganization getCurrentAccountOrg(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        return account.getPlatformOrganization();
    }

    /**
     * 获取真实机构ID
     * @return
     */
    public static String getCurrentAccountRealOrgId(){
        RealOrganization realOrganization = getCurrentAccountRealOrganization();
        if(realOrganization == null){
            return null;
        }
        return realOrganization.getId();
    }

    /**
     * 获取真实机构code
     * @return
     */
    public static String getCurrentAccountRealOrgCode(){
        RealOrganization realOrganization = getCurrentAccountRealOrganization();
        if(realOrganization == null){
            return null;
        }
        return realOrganization.getCode();
    }

    /**
     * 获取真实机构名称
     * @return
     */
    public static String getCurrentAccountRealOrgName(){
        RealOrganization realOrganization = getCurrentAccountRealOrganization();
        if(realOrganization == null){
            return null;
        }
        return realOrganization.getName();
    }

    /**
     * 获取当前账户的真实用户信息
     * @return
     */
    public static RealOrganizationUser getCurrentAccountRealUser(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        return account.getRealUser();
    }

    /**
     * 获取真实用户ID
     * @return
     */
    public static String getCurrentAccountRealUserId(){
        RealOrganizationUser realOrganizationUser = getCurrentAccountRealUser();
        if(realOrganizationUser == null){
            return null;
        }
        return realOrganizationUser.getId();
    }

    /**
     * 获取真实用户编码
     * @return
     */
    public static String getCurrentAccountRealUserCode(){
        RealOrganizationUser realOrganizationUser = getCurrentAccountRealUser();
        if(realOrganizationUser == null){
            return null;
        }
        return realOrganizationUser.getCode();
    }

    /**
     * 获取真实用户名称
     * @return
     */
    public static String getCurrentAccountRealUserName(){
        RealOrganizationUser realOrganizationUser = getCurrentAccountRealUser();
        if(realOrganizationUser == null){
            return null;
        }
        return realOrganizationUser.getName();
    }

    /**
     * 获取ID
     * @return
     */
    public static String getCurrentAccountId(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        return account.getId();
    }

    /**
     * 获取CODE
     * @return
     */
    public static String getCurrentAccountCode(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        return account.getCode();
    }

    /**
     * 获取NAME
     * @return
     */
    public static String getCurrentAccountName(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        return account.getName();
    }

    /**
     * 获取租户ID
     * @return
     */
    public static String getCurrentAccountTenantId(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        return account.getTenantId();
    }

    /**
     * 获取租户Name
     * @return
     */
    public static String getCurrentAccountTenantName(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        return account.getTenantName();
    }

    /**
     * 获取当前账户，真实部门用户
     * @return
     */
    public static DepartmentUser getCurrentAccountRealDepartmentUser(){
        RealOrganizationUser realOrganizationUser = getCurrentAccountRealUser();
        if(realOrganizationUser == null){
            return null;
        }
        if(realOrganizationUser instanceof DepartmentUser){
            return (DepartmentUser) realOrganizationUser;
        }
        return null;
    }

    /**
     * 获取当前账户真实机构
     * @return
     */
    public static RealOrganization getCurrentAccountRealOrganization(){
        Account account = getCurrentAccount();
        if(account == null){
            return null;
        }
        if(account.getRealUser() == null){
            return null;
        }
        return account.getRealUser().getOrganization();
    }

    /**
     * 获取当前账户真实部门（属于机构的一种）
     * @return
     */
    public static Department getCurrentAccountDepartment(){
        RealOrganization realOrganization = getCurrentAccountRealOrganization();
        if(realOrganization == null){
            return null;
        }
        if(realOrganization instanceof Department){
            return (Department) realOrganization;
        }
        return null;
    }

    /**
     * 得到登录用户信息Map
     *
     * @return 用户信息
     */
    public static Map<String, Object> getCurrentInfo() {
        Department currentDept = getCurrentAccountDepartment();
        Map<String, Object> values = new HashMap();
        values.put("@USER_ID@", getCurrentAccountRealUserId());
        values.put("@USER_CODE@", getCurrentAccountRealUserCode());
        values.put("@USER_NAME@", getCurrentAccountRealUserName());
        values.put("@USER_GROUP_COMPANY_ID@", currentDept == null?null:currentDept.getGroupCompanyId());
        values.put("@USER_GROUP_COMPANY_NAME@", currentDept == null?null:currentDept.getGroupCompanyName());
        values.put("@USER_COMPANY_ID@", currentDept == null?null:currentDept.getCompanyId());
        values.put("@USER_COMPANY_NAME@", currentDept == null?null:currentDept.getCompanyName());
        values.put("@DEPT_ID@", currentDept == null?null:currentDept.getId());
        values.put("@DEPT_CODE@", currentDept == null?null:currentDept.getCode());
        values.put("@DEPT_NAME@", currentDept == null?null:currentDept.getName());
        values.put("@NOW_DATE@", DateUtils.formatDate(new Date()));
        values.put("@NOW_MONTH@", DateUtils.formatDate(new Date(), "yyyy-MM"));
        values.put("@NOW_TIME@", DateUtils.formatDateTime(new Date()));
        values.put("@NOW_YEAR@", DateUtils.formatDate(new Date(), "yyyy"));
        values.put("@NOW_ONLYMONTH@", DateUtils.formatDate(new Date(), "MM"));
        return values;
    }

}
